const Parse = require('parse/node');
const _=require('lodash');
const config=require("../config/config");
const template_file = config.template_file;
const WhiteListObj = Parse.Object.extend("AutoBorrow_WhiteList");
const BorrowListObj=Parse.Object.extend("AutoBorrow_BorrowList");
const KindObj=Parse.Object.extend("AutoBorrow_Kinds");
const ParseHelper = require('../helpers/parse');
const ExcelService = require("./excel");
const moment=require('moment');
const KindService=require('./kind');
//从excel文件中导入多个名单
async function importNameListFromExcelFile(filePath,dataColumnNumber=1,firstDataRowNumber=2){
    const whiteListDict=await ExcelService.parseExcelFileNameLists(filePath,dataColumnNumber,firstDataRowNumber);
    return importNameListDict(whiteListDict);
}

//使用名单字典导入多个名单到数据库，返回创建的名单数与更新的名单数
//输入样例:{ Sheet1: [ '111', '222' ], Sheet2: [ 'aa', 'bb', 'cc' ] }
//输出样例:{createCount:1,updateCount:1}
async function importNameListDict(whiteListDict){
    const whiteListNames=Object.keys(whiteListDict);
    //查询数据库中同名的名单
    const query = new Parse.Query(WhiteListObj);
    query.notEqualTo('isDeleted', true);
    query.containedIn('name', whiteListNames);
    const existWhiteListObjs= await query.find({ useMasterKey: true });
    //更新已有名单
    existWhiteListObjs.forEach(whiteListObj=>{
        const name=whiteListObj.get("name");
        whiteListObj.set("usernames",whiteListDict[name]);
        _followNameList(whiteListObj.get("followers"),whiteListObj.get("usernames"));
    });
    const existNameListNames=existWhiteListObjs.map(o=>o.get("name"));
    //创建新名单
    const newWhiteListObjs=[];
    whiteListNames.forEach(name=>{
        if(existNameListNames.indexOf(name)<0){
            const whiteList = new WhiteListObj();
            whiteList.set("name",name);
            whiteList.set("usernames", whiteListDict[name]);
            whiteList.set("followers",{});//初始化名单跟踪
            newWhiteListObjs.push(whiteList);
        }
    });
    //合并数据，执行更新
    const allWhiteListObjs=[...existWhiteListObjs,...newWhiteListObjs];
    await Parse.Object.saveAll(allWhiteListObjs,{ useMasterKey: true });
    //返回创建的名单数与更新的名单数
    return {createCount:newWhiteListObjs.length,updateCount:existWhiteListObjs.length}
}


//创建名单
async function add(name,usernames,kindId){
    const whiteListObj=new WhiteListObj({name,usernames,kindId});
    await whiteListObj.save(null,{ useMasterKey: true });
    return ParseHelper.toJSON(whiteListObj);
}

//删除
async function remove(whiteListId){
    const whiteListObj=WhiteListObj.createWithoutData(whiteListId);
    whiteListObj.set("isDeleted",true);
    await whiteListObj.save(null,{ useMasterKey: true });
    return ParseHelper.toJSON(whiteListObj);
}


//添加成员到名单
async function add_user(whiteListId,username){
    const whiteListObj=WhiteListObj.createWithoutData(whiteListId);
    whiteListObj.addUnique("usernames",username);
    await whiteListObj.save(null,{ useMasterKey: true });
    return ParseHelper.toJSON(whiteListObj);
}

async  function getNameListByName(name){
    const query = new Parse.Query(WhiteListObj);
    query.equalTo('name',name);
    query.notEqualTo('isDeleted',true);
    return  query.first({ useMasterKey: true }).then(ParseHelper.toJSON);
}

async function getUserWhiteList(username,kindId){
    const query = new Parse.Query(WhiteListObj);
    query.equalTo('usernames',username);
    query.equalTo('kindId',kindId);
    query.notEqualTo('isDeleted',true);
    return  query.first({ useMasterKey: true }).then(ParseHelper.toJSON);
}

async function getListByUsers(usernames){
    const query = new Parse.Query(WhiteListObj);
    query.notEqualTo('isDeleted', true);
    query.containedIn('usernames', usernames);
    query.limit(9999);
    return  query.find({ useMasterKey: true }).then(ParseHelper.toJSONList);
}

//从名单中删除成员
async function remove_user(whiteListId,username){
    const whiteListObj=WhiteListObj.createWithoutData(whiteListId);
    whiteListObj.remove("usernames",username);
    await whiteListObj.save(null,{ useMasterKey: true });
    return ParseHelper.toJSON(whiteListObj);
}
async function getWhiteListBorrowList(whiteListId){
    const query = new Parse.Query(BorrowListObj);
    query.notEqualTo('isDeleted', true);
    query.equalTo('whiteListId', whiteListId);
    query.limit(9999);
    return query.find({ useMasterKey: true }).then(ParseHelper.toJSONList);
}

async function getManagersByUsernames(usernames){
    const UserObj = Parse.Object.extend("v5_user");
    const query = new Parse.Query(UserObj);
    query.containedIn('username', usernames);
    query.select(['username', 'showName']);
    return query.find({ useMasterKey: true }).then(users => {   
        return users.map(user => ({
            username: user.get('username'),
            showName: user.get('showName'),
        }));
    });
}

async function getAllWhiteList(){
    const query = new Parse.Query(WhiteListObj);
    query.notEqualTo('isDeleted',true);
    query.limit(9999);
    const white_list=await query.find({ useMasterKey: true }).then(ParseHelper.toJSONList);
    const usernames= white_list.map(l=>l.manager);
    const managers= await getManagersByUsernames(usernames);
    const result=white_list.map(async l=>{
        const kindQuery = new Parse.Query(KindObj);
        const kind=await  kindQuery.get(l.kindId,{ useMasterKey: true }).then(ParseHelper.toJSON);
        const borrow_list=await getWhiteListBorrowList(l.objectId);
        const manager = managers.find(m => m.username === l.manager);
        const getGoods=borrow_list.filter(b=>b.hasUsed===true);
        const returnedGoods=borrow_list.filter(b=>b.hasReturn===true);
        console.log("manager",manager)
        return {

            ...l,
            manager:manager.showName?manager.showName+"("+manager.username+")":"",
            apply_count:getGoods.length||0,returned_count:returnedGoods.length||0,kind:kind.name
        }
    });
    return await Promise.all(result)
}

async function getAllWhiteListInfo(isClosed){
    const query = new Parse.Query(WhiteListObj);
    query.notEqualTo('isDeleted',true);
    if(isClosed===true){
        query.equalTo('isClosed',true);
    }else{
        query.notEqualTo('isClosed',true);
    }
    query.limit(9999);
    return query.find({ useMasterKey: true }).then(ParseHelper.toJSONList);
}

// 获取白名单成员信息
async function getWhiteListMembers(whiteListId) {
    const UserObj = Parse.Object.extend("v5_user");
    
    // 首先获取白名单信息
    const query = new Parse.Query(WhiteListObj);
    query.equalTo('objectId', whiteListId);
    query.notEqualTo('isDeleted', true);
    const whiteList = await query.first({ useMasterKey: true });
    
    if (!whiteList) {
        return [];
    }
    
    const usernames = whiteList.get('usernames') || [];
    
    if (usernames.length === 0) {
        return [];
    }
    
    // 根据用户名获取用户详细信息
    const userQuery = new Parse.Query(UserObj);
    userQuery.containedIn('username', usernames);
    userQuery.select(['username', 'showName',]);
    const users = await userQuery.find({ useMasterKey: true });
    
    return users.map(user => ({
        username: user.get('username'),
        showName: user.get('showName'),
    }));
}

async function update(id,key,value){
    const whiteListObj= WhiteListObj.createWithoutData(id);
    whiteListObj.set(key,value);
    await whiteListObj.save(null,{ useMasterKey: true });
    return ParseHelper.toJSON(whiteListObj);
}

//检查用户数据是否合规,有错误返回错误原因，
/*
result={
error:"错误原因", //无错误时无此项
exampleRows, //样例数据，前5行
mappedExampleRows, //对字段进行映射的样例数据
filePath, //文件路径
count //数据行数
}
 */
async function checkExcelFile(filePath,nameRowNumber,firstDataRowNumber,fieldsMapping){
    const usersData=await ExcelService.parseExcelFileFirstSheet(filePath,nameRowNumber,firstDataRowNumber);
    if(usersData.length>0){
        //取得前5行作为样例数据
        var exampleRows=_.take(usersData,5);
        var needDeleteExtra = false;
        if(template_file==='users_kmust.xlsx'||template_file==='users_seu.xlsx'){
            needDeleteExtra = true;
            exampleRows = exampleRows.map(u=>addYHM(u));
        }
        var mappedExampleRows=exampleRows.map(row=>mappingUserData(row,fieldsMapping,needDeleteExtra));
        const result={
            exampleRows,
            mappedExampleRows,
            filePath,
            count:usersData.length
        };
        if(!mappedExampleRows[0].hasOwnProperty("username")){
            result.error= "缺少用户名字段"
        }
        return result;
    }else{
        return {error:'文件内容为空'};
    }
}

//根据fieldsMapping修改userData中的key
function mappingUserData(userData, fieldsMapping,needDeleteExtra=false){
    const mappedUserData={...userData};//复制要处理的数据
    Object.keys(mappedUserData).forEach(function(key) {
        const dbFieldName=fieldsMapping[key];
        if(dbFieldName){
            mappedUserData[dbFieldName] = mappedUserData[key];
            delete mappedUserData[key];
        }else{
            if(needDeleteExtra===true){
                delete mappedUserData[key];
            }
        }
    });
    return mappedUserData;
}

function addUsername(user){
    if(!user.hasOwnProperty("username")&&user.hasOwnProperty("studentNumber")){
        user["username"]=user.studentNumber;
    }
    return user;
}

function addYHM(user){
    if(!user.hasOwnProperty("用户名")&&user.hasOwnProperty("学号")){
        user["用户名"]=user.学号;
    }
    return user;
}

async function importExcelFile(filePath,nameRowNumber,firstDataRowNumber,fieldsMapping,id){
    var usersData=await ExcelService.parseExcelFileFirstSheet(filePath,nameRowNumber,firstDataRowNumber);
    var needDeleteExtra = false;
    if(template_file==='users_kmust.xlsx'||template_file==='users_seu.xlsx'){
        needDeleteExtra = true;
        usersData = usersData.map(u=>addYHM(u));
    }
    var mappedUsersData=usersData.map(ud=>mappingUserData(ud,fieldsMapping,needDeleteExtra));
    const usernames = mappedUsersData.map(data=>data.username);
    return _importMember(usernames,id);
}

async function _importMember(usernames,id){
    console.log('usernames,id',usernames,id)
    const uniqUsernames = _.uniq(usernames);//文件数据去重
    const repeatCount = usernames.length-uniqUsernames.length;//文件数据重复个数
    //获取原始students,方便比对最后结果
    const query = new Parse.Query(WhiteListObj);
    query.equalTo('objectId',id);
    query.notEqualTo('isDeleted',true);
    query.select('usernames');
    const oriNameList = await query.first({ useMasterKey: true });
    const jsonOriNameList = ParseHelper.toJSON(oriNameList);
    const oriStudents = jsonOriNameList.usernames||[];//数据库原始数据
    //添加成员
    const newNameList = WhiteListObj.createWithoutData(id);
    uniqUsernames.forEach(username=>{
        newNameList.addUnique('usernames',username);
    });
    await newNameList.save(null,{ useMasterKey: true });
    const jsonNewReportBox = ParseHelper.toJSON(newNameList);
    const newStudents = jsonNewReportBox.usernames;
    const successCount = newStudents.length-oriStudents.length;
    const existCount = uniqUsernames.length-successCount;
    return {repeatCount,existCount,successCount};
}
async function getNameListById(id){
    const query = new Parse.Query(WhiteListObj);
    return query.get(id,{ useMasterKey: true }).then(ParseHelper.toJSON);
}

async function getKindsByIds(ids){
    const query = new Parse.Query(KindObj);
    query.notEqualTo('isDeleted', true);
    query.containedIn('objectId', ids);
    query.limit(999);
    return query.find({ useMasterKey: true }).then(ParseHelper.toJSONList);
}

async function getUserKinds(username){
    const query = new Parse.Query(WhiteListObj);
    query.equalTo('usernames',username);
    query.notEqualTo('isDeleted',true);
    query.notEqualTo('isClosed',true);
    const list=await  query.find({ useMasterKey: true }).then(ParseHelper.toJSONList);
    const kindIds=list.map(l=>l.kindId);
    const kinds=await getKindsByIds(kindIds);
    const kindDict=_.keyBy(kinds,"objectId");
    const now=moment().format('YYYY-MM-DD HH:mm')
    return list.map(l=>{
        const kind=kindDict[l.kindId];
        const _apply_times=_.orderBy(l.apply_times, ['day', 'begin'], ['asc', 'asc']);
        const a_apply_times=_apply_times.filter(t=>t.day+" "+t.end>=now);
        const apply_times=a_apply_times.map(t=>{
            return{
                label:t.day+" "+t.begin+"~"+t.end,
                value:t.day+" "+t.begin+"~"+t.end,
            }
        })
        return {...l,kind,apply_times}
    })
}


module.exports={
    importNameListFromExcelFile,
    add,
    remove,
    add_user,
    remove_user,
    update,
    checkExcelFile,
    importExcelFile,
    getNameListById,
    getNameListByName,
    getUserKinds,
    getAllWhiteList,
    getUserWhiteList,
    getListByUsers,
    getAllWhiteListInfo,
    getWhiteListMembers
};